require 'missile'
class Weapon
  attr_reader :name, :reload_timer, :reload_time, :cooldown_timer, :cooldown_time, :recoil, :magazine, :magazine_max, :speed, :ammo_type
  SHOULDER_HEIGHT = 0.25
  WAIST_HEIGHT = 0
  CROSSHAIR_DISTANCE = 50
  def initialize(window, unit)
    @window, @unit = window, unit
    @reload_timer = 0
    @name = self.class.to_s if !defined?(@name)
    @image_crosshair = Images["media/crosshair.png"]
  end
  def update
    $game.play(@reload_sound) if @reload_timer == 1 and @reload_sound
    if @reload_timer > 0
      @reload_timer -= 1
      @magazine = @magazine_max if @reload_timer == 0
    end
    if @cooldown_timer > 0
      @cooldown_timer -= 1
    end
  end
  
  def draw
    unless @unit.dead
      factor_x = (@unit.direction == :left) ? 1 : -1
      @image.draw_rot(@unit.x, @window.height - @unit.y - @unit.height * @weapon_height_adjust, ZOrder::Weapons, @unit.weapon_angle.to_i, 0.5, 0.5, factor_x, 1)
      if @unit.human?
        @image_crosshair.draw(@unit.x + offset_x(@unit.weapon_angle, CROSSHAIR_DISTANCE) - @image_crosshair.width/2, @window.height - @unit.y - @unit.height * @weapon_height_adjust + offset_y(@unit.weapon_angle, CROSSHAIR_DISTANCE) - @image_crosshair.height/2, ZOrder::HUD)
      end
    end
  end
  
  def unit_died
    WeaponMissile.new($game, @unit, @unit.x, @unit.y - @unit.height * 0.3, @unit.weapon_angle, 5, @image)
  end
  
  def fire
    return false if @reload_timer != 0 or @cooldown_timer != 0
    @cooldown_timer = @cooldown_time
    @magazine -= 1
    reload if @magazine == 0
    $game.play(@fire_sound) if @fire_sound
    true
  end
  
  def reload
    @reload_timer = @reload_time
    @unit.notify_reloading
  end
end

class GrenadeLauncher < Weapon
  def initialize(window, unit)
    super(window, unit)
    @name = "Grenade Launcher"
    @recoil, @magazine_max, @reload_time, @cooldown_time, @speed = 3, 1, 110, 0, 18
    @magazine, @cooldown_timer = @magazine_max, @cooldown_time
    @weapon_height_adjust = SHOULDER_HEIGHT
    @fire_sound = Gosu::Sample.new(window, "media/fire.wav")
    @reload_sound = Gosu::Sample.new(window, "media/reload.wav")
    @image = Images["media/grenadelauncher.png"]
    @ammo_type = GrenadeLauncherRound
  end
  
  def fire
    return false if !super
    DebugOut.out "GrenadeLauncher fired"
    #if color is too dark, brighten it
    col = @unit.color_uniform
    colc = [col % 256]
    colc << col / 256 % 256
    colc << col / 256 / 256 % 256
    diff = 256 - (colc.inject { |a, b| a + b }) / 3
    if diff > 0
      diff /= 3
      ###use rgb_to_color
      col = [(colc[0] + diff), 255].min + [(colc[1] + diff), 255].min * 256 + [(colc[2] + diff), 255].min * (256 ** 2) + 0xff000000
    end
    c = @ammo_type.new(@window, @unit, @unit.x, @unit.y + @unit.height * 0.25, @unit.weapon_angle, col, @speed)
  end
end

class PoisonGrenadeLauncher < Weapon
  def initialize(window, unit)
    super(window, unit)
    @name = "Poison Grenade Launcher"
    @recoil, @magazine_max, @reload_time, @cooldown_time, @speed = 3, 1, 110, 0, 18
    @magazine, @cooldown_timer = @magazine_max, @cooldown_time
    @weapon_height_adjust = SHOULDER_HEIGHT
    @fire_sound = Gosu::Sample.new(window, "media/fire.wav")
    @reload_sound = Gosu::Sample.new(window, "media/reload.wav")
    @image = Images["media/grenadelauncher.png"]
    @ammo_type = PoisonGrenadeLauncherRound
  end
  
  def draw
    unless @unit.dead
      factor_x = (@unit.direction == :left) ? 1 : -1
      @image.draw_rot(@unit.x, @window.height - @unit.y - @unit.height * @weapon_height_adjust, ZOrder::Weapons, @unit.weapon_angle.to_i, 0.5, 0.5, factor_x, 1, 0xff7fff7f)
      if @unit.human?
        @image_crosshair.draw(@unit.x + offset_x(@unit.weapon_angle, CROSSHAIR_DISTANCE) - @image_crosshair.width/2, @window.height - @unit.y - @unit.height * @weapon_height_adjust + offset_y(@unit.weapon_angle, CROSSHAIR_DISTANCE) - @image_crosshair.height/2, ZOrder::HUD)
      end
    end
  end

  
  def fire
    return false if !super
    DebugOut.out "GrenadeLauncher fired"
    #if color is too dark, brighten it
    col = @unit.color_uniform
    colc = [col % 256]
    colc << col / 256 % 256
    colc << col / 256 / 256 % 256
    diff = 256 - (colc.inject { |a, b| a + b }) / 3
    if diff > 0
      diff /= 3
      ###use rgb_to_color
      col = [(colc[0] + diff), 255].min + [(colc[1] + diff), 255].min * 256 + [(colc[2] + diff), 255].min * (256 ** 2) + 0xff000000
    end
    c = @ammo_type.new(@window, @unit, @unit.x, @unit.y + @unit.height * 0.25, @unit.weapon_angle, col, @speed)
  end
end


class Grenades < Weapon
  def initialize(window, unit)
    super(window, unit)
    @name = "Hand Grenades"
    @recoil, @magazine_max, @reload_time, @cooldown_time, @speed = 0, 1, 50, 0, 10
    @magazine, @cooldown_timer = @magazine_max, @cooldown_time
    @weapon_height_adjust = WAIST_HEIGHT
    @ammo_type = Grenade
    @fire_sound = Gosu::Sample.new(window, "media/throw.wav")
    #@reload_sound = Gosu::Sample.new(window, "media/reload.wav")
    @image = Images["media/grenade.png"]
  end
  
  def fire
    return false if !super
    DebugOut.out "Grenade thrown"
    c = @ammo_type.new(@window, @unit, @unit.x, @unit.y + @unit.height * 0.25, @unit.weapon_angle, 0xffffffff, @speed)
  end
end


class Rifle < Weapon
  def initialize(window, unit)
    super(window, unit)
    @name = "Rifle"
    @recoil, @magazine_max, @reload_time, @cooldown_time, @speed = 1, 6, 80, 20, 50
    @magazine, @cooldown_timer = @magazine_max, 0
    @weapon_height_adjust = SHOULDER_HEIGHT
    @fire_sound = Gosu::Sample.new(window, "media/pistol.wav")
    @reload_sound = Gosu::Sample.new(window, "media/reload.wav")
    @image = Images["media/rifle.png"]
    @ammo_type = RifleRound
  end
  
  def fire
    return false if !super
    DebugOut.out "Rifle fired"
    c = @ammo_type.new(@window, @unit, @unit.x, @unit.y + @unit.height * 0.25, @unit.weapon_angle, 0xffffffff, @speed)
  end
end